package com.openatc.agent.service.impl;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.openatc.agent.service.FeatureRequest;
import com.openatc.agent.service.FeatureService;
import com.openatc.agent.utils.RedisTemplateUtil;
import com.openatc.comm.data.MessageData;
import com.openatc.core.model.InnerError;
import com.openatc.core.model.RESTRet;
import com.openatc.core.util.DateUtil;
import com.openatc.model.model.Channel;
import com.openatc.model.model.Phase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

import static com.openatc.core.common.IErrorEnumImplInner.E_109;
import static com.openatc.core.common.IErrorEnumImplInner.E_110;

/**
 * @author ：panleilei
 * @description
 * @modified By：
 * @version:
 * @date ：Created in 2024/8/16 14:16
 */
@Service(value = "feature/channel")
public class FeatureChannelRequest extends FeatureRequest {
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;
    private String keyType = "response:feature/channel:";
    @Autowired
    private FeatureService featureService;


    /**
     * 成功上载通道参数
     * @param requestData
     * @param responseData
     * @return
     */
    @Override
    public RESTRet successGetProcess(MessageData requestData, RESTRet responseData) {
        MessageData messageData = (MessageData) responseData.getData();
        updateChannelCache(messageData.getAgentid(),messageData);
        JsonElement data = messageData.getData();
        if (data != null) {
            JsonObject channelObj = data.getAsJsonObject();
            // todo 避免此除出异常导致上载功能出问题，影响测试，测试结束后，此处没问题，去掉try catch
            try {
                // 填充通道方向
                if (channelObj.has("channelList")) {
                    // check need fill
                    List<Channel> channels = gson.fromJson(channelObj.get("channelList"), new TypeToken<List<Channel>>(){}.getType());
                    if (checkFillChannelDirection(channels)) {
                        // 相位参数和跟随相位参数，要从数据库中获取，如果数据库中不存在，则不进行填充
                        MessageData feature = featureService.getFeatures(messageData.getAgentid());
                        if (feature == null) {
                            logger.warning("Fill channel direction failed! Get feature from db failed! AgentId: " + messageData.getAgentid());
                            return super.successGetProcess(requestData, responseData);
                        }
                        JsonObject featureData = feature.getData().getAsJsonObject();
                        List<Phase> phases = gson.fromJson(featureData.get("phaseList"), new TypeToken<List<Phase>>(){}.getType());
                        JsonArray overlaplList = featureData.get("overlaplList").getAsJsonArray();
                        fillChannelDirection(channelObj.get("channelList").getAsJsonArray(), phases, overlaplList);
                    }
                }
            } catch (Exception e) {
                logger.warning("fill channel direction failed!");
                e.printStackTrace();
            }
        }
        return super.successGetProcess(requestData, responseData);
    }



    /**
     * 成功下载通道参数
     * @param requestData
     * @param responseData
     * @return
     */
    @Override
    public RESTRet successSetProcess(MessageData requestData, RESTRet responseData) {
        String agentid = requestData.getAgentid();
        updateChannelCache(agentid,requestData);
        return super.successSetProcess(requestData, responseData);
    }

    /**
     * 向信号机请求相位参数应答失败
     * @param requestData
     * @param responseData
     * @return
     */
    @Override
    public RESTRet failureGetProcess(MessageData requestData, RESTRet responseData) {
        InnerError innerError = (InnerError) responseData.getData();
        // 上次请求未结束/信号机应答超时，从缓存中获取数据
        if (innerError.getErrorCode().equals(E_110.getErrorCode()) ) {
            return redisTemplateUtil.getCacheData(requestData);
        }
        else if (innerError.getErrorCode().equals(E_109.getErrorCode()) ) {
            return redisTemplateUtil.getCacheData(requestData);
        }
        return super.failureGetProcess(requestData, responseData);
    }

    /**
     * 更新相位缓存数据
     * @param agentid
     * @param data
     */
    private void updateChannelCache(String agentid, MessageData data) {
        String key = keyType + agentid;
        MessageData deepCopy = gson.fromJson(gson.toJsonTree(data), MessageData.class);
        deepCopy.setOperation("get-response");
        deepCopy.setCreatetime(DateUtil.date2str(new Date()));
        redisTemplateUtil.setValue(key,gson.toJson(deepCopy));
    }
}
